# -*- coding: utf-8 -*-
import json
import logging
import re

from django.views.decorators.http import require_GET, require_POST

from api.transaction.handler import get_user_transactions
from common.account.db.account import get_account, get_logon_info, set_black_status, get_black_account, \
    get_financial_accounts, get_account_by_chn_ip, hide_phone_username
from common.coupon.db import list_coupon, get_coupon_stats
from common.stats import MG_BIGBANG_COLL as mg
from common.stats.account import get_account_aggr
from common.transaction.db import list_transaction, map_transaction_title, parse_query_title
from common.utils.api import token_required, mask_string
from common.utils.decorator import response_wrapper
from common.utils.exceptions import DataError
from common.utils.export import redirect_to_file, gen_filename
from common.utils.respcode import StatusCode
from common.utils.tz import utc_to_local_str, ts_to_local_date_str
from common.black_account.db import get_withdraw_black_list
from common.black_account.db import WITHDRAW_BLACK_TYPE
from common.system_recharge.db import get_system_recharge_detail_total
from common.utils.currency import convert_fen_to_yuan
from common.transaction.db import get_withdraw_count_amount
from common.cache import redis_cache

_LOGGER = logging.getLogger(__name__)


@require_GET
@response_wrapper
@token_required
def get_account_info(req, account_id):
    account_id = long(account_id)
    account = get_account(account_id)
    if not account:
        raise DataError(status=StatusCode.INVALID_USER)
    account = account.as_dict()
    account.pop("password")
    account.update(get_logon_info(account_id))
    account.update(get_account_aggr(account_id))
    account['created_at'] = utc_to_local_str(account['created_at'])
    account['updated_at'] = utc_to_local_str(account['updated_at'])
    account['system_amount'] = convert_fen_to_yuan(get_system_recharge_detail_total(account_id))
    # account['witdraw_wait_amount'], account['withdraw_wait_total'] = get_withdraw_count_amount(account_id)
    # for mobile console
    account["total_recharge"] = account[
        'user_stats'].get("recharge", {}).get("total", 0)
    account["total_win"] = account['user_stats'].get("win", {}).get("total", 0)
    if req.user_id not in [16, 17]:
        account['token'] = u'不能告诉你'
    account = hide_phone_username(account)
    phone = account['phone']
    if phone:
        account['phone'] = mask_string(account['phone'][2:])
    if re.match(r'\d{13}', account['user_name']) and account['user_name'].startswith('86'):
        account['user_name'] = mask_string(account['user_name'][2:])
    financial_accounts = get_financial_accounts(account_id)
    for item in financial_accounts:
        account.update({
            item.type: mask_string(item.account)
        })
    black_lists = get_withdraw_black_list()
    black_uids = black_lists.get('black_uid', [])
    test_uids = black_lists.get('test_uid', [])
    account['black_uid'] = True if str(account['id']) in black_uids else False
    account['test_uid'] = True if str(account['id']) in test_uids else False
    account['coupon_stats'] = get_coupon_stats(account_id)
    return account


@require_GET
@response_wrapper
@token_required
def get_coupon_list(req, account_id):
    query_dct = req.GET.dict()
    items, total_count = list_coupon(query_dct)
    coupon_stats = get_coupon_stats(account_id)

    resp_items = []
    for item in items:
        item.created_at = utc_to_local_str(item.created_at)
        item.updated_at = utc_to_local_str(item.updated_at)
        item.start_ts = ts_to_local_date_str(item.start_ts)
        item.expire_ts = ts_to_local_date_str(item.expire_ts)
        resp_items.append(item.as_dict())
    return {'list': resp_items, 'page': query_dct.get('page', 1), 'stats': coupon_stats,
            'size': len(resp_items), 'total_count': total_count}


@require_GET
@response_wrapper
@token_required
def get_recharge_list(req, account_id):
    query_dct = req.GET.dict()
    page = int(query_dct.get('page', 0))
    size = int(query_dct.get('size', 0))

    # only_need: price, created_at
    items, total_count = get_user_transactions(long(account_id), page, size, 1)
    return {'list': items, 'page': page or 1,
            'size': len(items), 'total_count': total_count}


@require_GET
@response_wrapper
@token_required
def get_transaction_list(req, account_id):
    query_dct = req.GET.dict()
    query_dct['user_id'] = account_id
    query_dct['$orderby'] = '-id'
    export = query_dct.pop('$export', None)
    if export:
        filename = gen_filename('transaction')
        header = ['id', 'created_at', 'type', 'title', 'price', 'balance', 'order_id']
        cn_header = ['id', u'时间', u'种类', u'名称', u'金额', u'用户余额', u'订单编号']
    if 'title' in query_dct:
        query_dct = parse_query_title(query_dct)
    items, total_count, total_income, total_outcome = list_transaction(int(account_id), query_dct)
    items = map_transaction_title(items)
    resp_items = []
    for item in items:
        item.id = str(item.id)
        item.order_id = str(item.order_id or '')
        item.created_at = utc_to_local_str(item.created_at)
        item.updated_at = utc_to_local_str(item.updated_at)
        if export:
            resp_items.append([item.as_dict().get(x, '-') for x in header])
        else:
            resp_items.append(item.as_dict())
    if export:
        return redirect_to_file(resp_items, cn_header, filename)
    return {'list': resp_items, 'page': query_dct.get('page', 1), 'total_outcome': total_outcome,
            'size': len(resp_items), 'total_count': total_count, 'total_income': total_income}


def get_account_resp(account):  # 将account转换成返回数据
    account = account.as_dict()
    extend = json.loads(account.get('extend')) if account.get('extend') else {}
    user_stats = mg.user_stats.find_one({'_id': account.get('id', 0)}) or {}
    if account['phone']:
        account['phone'] = mask_string(account.get('phone', ''))
    if 'created_at' or 'updated_at' in account:
        account['created_at'] = utc_to_local_str(account['created_at'])
        account['updated_at'] = utc_to_local_str(account['updated_at'])
    account_resp_item = account
    account_resp_item.update({
        'user_id': account.get('id'),  # 用户ID
        'user_name': account.get('user_name'),  # 用户昵称
        'channel': account.get('channel'),  # 渠道号
        'status': account.get('status'),  # 当前状态
        'blackfor': u'%s' % (extend.get('blackfor', '')),  # 拉黑原因
        'black_time': extend.get('black_time', ''),  # 拉黑时间
        'black_operator': extend.get('black_operator', ''),  # 拉黑操作人
        'old_status': extend.get('old_status', ''),  # 上次状态
        'total_recharge': user_stats.get('recharge', {}).get('total', 0),  # 充值金额
        'total_win': user_stats.get('win', {}).get('total', 0),  # 中奖金额
        'total_withdraw': user_stats.get('withdraw', {}).get('total', 0)  # 提现金额
    })
    return account_resp_item


@require_GET
@response_wrapper
@token_required
def search_black_account(req):
    query_dct = req.GET.dict()
    account_items, total_count = get_black_account(query_dct)
    account_resp = []
    if account_items is not None:
        black_lists = get_withdraw_black_list()
        black_uids = black_lists.get(WITHDRAW_BLACK_TYPE.BLACK_UID, [])
        black_uids = [int(black_uid) for black_uid in black_uids]
        test_uids = black_lists.get(WITHDRAW_BLACK_TYPE.TEST_UID, [])
        test_uids = [int(test_uid) for test_uid in test_uids]
        sales_uids = black_lists.get(WITHDRAW_BLACK_TYPE.BLACK_SALES, [])
        sales_uids = [int(sale_uid) for sale_uid in sales_uids]
        op_uids = black_lists.get(WITHDRAW_BLACK_TYPE.BLACK_OPERATIONS, [])
        op_uids = [int(op_uid) for op_uid in op_uids]
        for account in account_items:
            account_status = ''
            if account.phone and account.user_name:
                if account.user_name == account.phone or account.user_name == account.phone[2:]:
                    account.user_name = mask_string(account.user_name)
            if not account.phone and account.user_name:
                if len(account.user_name) == 11 and account.user_name[0] in ['1', '8']:
                    account.user_name = mask_string(account.user_name)
            account_resp_item = get_account_resp(account)
            financial_account = get_financial_accounts(account.id, show_brief_dct=True)
            if account.id in black_uids:
                account_resp_item.update({'withdraw_black': True})
            if account.id in test_uids + sales_uids + op_uids or account.status == 1024:
                if account.id in test_uids:
                    account_status += u'测试用户'
                    account_resp_item.update({'withdraw_test': True})
                if account.id in sales_uids:
                    account_status = ' '.join([u'电销活动用户', account_status])
                    account_resp_item.update({'withdraw_sales': True})
                if account.id in op_uids:
                    account_status = ' '.join([u'运营活动用户', account_status])
                    account_resp_item.update({'withdraw_ops': True})
                if account.status == 1024:
                    account_status = ' '.join([u'黑名单用户', account_status])
            else:
                account_status = u'一般用户'
            account_resp_item.update({'account_status': account_status})
            account_resp_item.update(financial_account)
            account_resp.append(account_resp_item)
    return {'list': account_resp, 'page': query_dct.get('$page', 1),
            'total_count': total_count, 'size': len(account_resp)}


@require_POST
@response_wrapper
@token_required
def update_blcak_account(req):
    admin_id = req.user_id
    params = json.loads(req.body)
    account_id = params.get('account_id')  # 操作对象ID
    reason = params.get('reason')  # 操作原因
    status = params.get('status')  # 操作行为，BLACK封号，UNBLACK解封

    operator_user = req.user.nickname  # 操作人

    if account_id is None or status not in ["BLACK", "UNBLACK"]:
        raise DataError(status=StatusCode.PARAM_REQUIRED)

    set_black_status(account_id, operator_user, reason, status, admin_id)
    return {}


@require_GET
@response_wrapper
@token_required
def get_account_chn_ip(req):
    query_dct = req.GET.dict()
    aid = query_dct.get("aid", None)
    ip = query_dct.get("ip", None)
    last_login_ip = query_dct.get("last_login_ip", None)

    resp_items = []
    if aid or ip:
        items, total_count = get_account_by_chn_ip(query_dct)
        if items:
            for item in items:
                account = item.as_dict()
                account.pop("password")
                account.update(get_logon_info(account['id']))
                account.update(get_account_aggr(account['id']))
                account['created_at'] = utc_to_local_str(account['created_at'])
                account['updated_at'] = utc_to_local_str(account['updated_at'])

                account["total_recharge"] = account[
                    'user_stats'].get("recharge", {}).get("total", 0)
                account["total_win"] = account['user_stats'].get("win", {}).get("total", 0)
                if req.user_id not in [16, 17]:
                    account['token'] = u'不能告诉你'
                account = hide_phone_username(account)
                phone = account['phone']
                if phone:
                    account['phone'] = mask_string(account['phone'][2:])
                if re.match(r'861[3,4,5,7,8]\d{9}', account['user_name']) or \
                        re.match(r'1[3,4,5,7,8]\d{9}', account['user_name']):
                    account['user_name'] = mask_string(account['user_name'][2:])
                financial_accounts = get_financial_accounts(account['id'])
                for item in financial_accounts:
                    account.update({
                        item.type: mask_string(item.account)
                    })

                resp_items.append(account)
    else:
        items, total_count = get_account_by_chn_ip(query_dct)
        if items:
            for item in items:

                account = {'ip': last_login_ip}
                account_info = get_account(int(item[0]))
                account.update(account_info.as_dict())
                account.pop("password")
                account.update(get_account_aggr(account['id']))
                account['created_at'] = utc_to_local_str(account['created_at'])
                account['updated_at'] = utc_to_local_str(account['updated_at'])

                account["total_recharge"] = account[
                    'user_stats'].get("recharge", {}).get("total", 0)
                account["total_win"] = account['user_stats'].get("win", {}).get("total", 0)
                if req.user_id not in [16, 17]:
                    account['token'] = u'不能告诉你'
                account = hide_phone_username(account)
                phone = account['phone']
                if phone:
                    account['phone'] = mask_string(account['phone'][2:])
                if re.match(r'861[3,4,5,7,8]\d{9}', account['user_name']) \
                        or re.match(r'1[3,4,5,7,8]\d{9}', account['user_name']):
                    account['user_name'] = mask_string(account['user_name'][2:])
                financial_accounts = get_financial_accounts(account['id'])
                for item in financial_accounts:
                    account.update({
                        item.type: mask_string(item.account)
                    })

                resp_items.append(account)

    return {'list': resp_items,'page': query_dct.get('$page', 1),
            'total_count': total_count, 'size': len(resp_items)}



